/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 *
 * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
 *
 * Contributor(s): 
 *  Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
 *  
 * If you didn't download this code from the following link, you should check
 * if you aren't using an obsolete version: http://www.isqlviewer.com
 */
package org.isqlviewer.ui;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import java.util.prefs.Preferences;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.isqlviewer.swing.EnhancedTable;
import org.isqlviewer.swing.SwingUtilities;
import org.isqlviewer.swing.action.SwingEventManager;
import org.isqlviewer.swing.table.EnhancedTableModel;
import org.isqlviewer.swing.table.ResultSetTableModel;
import org.isqlviewer.ui.laf.SortableHeaderRenderer;
import org.isqlviewer.util.LocalMessages;

/**
 * @author Mark A. Kobold &lt;mkobold at isqlviewer dot com&gt;
 * @version 1.0
 */
public class DataGrid extends AbstractApplicationView implements ListSelectionListener, ActionListener,
        DocumentListener {

    private NumberFormat nf = NumberFormat.getIntegerInstance();
    private EnhancedTable table = null;
    private JTextField txtFilter = new JTextField();
    private JLabel lblFilter = new JLabel();
    private JScrollPane jspTable = null;
    private Component glue = Box.createHorizontalGlue();
    private JLabel lblLocatr = new JLabel();
    private JLabel lblSearch = new JLabel(SwingUtilities.loadIconResource("search", 16));
    private JButton btnHider = new JButton();
    private JButton actionPageUp = new JButton("");
    private JButton actionPageDown = new JButton("");
    private LocalMessages messages = new LocalMessages("org.isqlviewer.ui.ResourceBundle");

    public void configureMenubar(JMenuBar menuBar) {

        // TODO Auto-generated method stub

    }

    public void disposeView(Preferences preferences) {

        // TODO Auto-generated method stub

    }

    public void initializeView() {

        // TODO Auto-generated method stub

    }

    public void doLayout(JComponent parentComponent, Preferences preferences, SwingEventManager eventManager) {

        table = new EnhancedTable();
        // TODO table.setDropTarget(new DropTarget(table, workbench.bookmarkDropper));
        table.setFont(table.getFont().deriveFont(10f));
        // table.putClientProperty(EnhancedTable.CLIENT_JPOPUP_MENU, workbench.tablePopupMenu);
        table.setDragEnabled(true);
        table.getSelectionModel().addListSelectionListener(this);
        jspTable = new JScrollPane(table);
        lblLocatr.setBorder(BorderFactory.createEtchedBorder());
        btnHider.setIcon(new SortableHeaderRenderer.BasicArrowIcon(SwingConstants.NORTH, 4));
        btnHider.setBorderPainted(false);
        btnHider.setFocusPainted(false);
        btnHider.addActionListener(this);
        // btnHider.setToolTipText(BasicUtilities.getString("Filter_Hide_Tip"));
        actionPageUp.addActionListener(this);
        actionPageUp.setBorderPainted(false);
        actionPageUp.setFocusPainted(false);
        // actionPageUp.setToolTipText(BasicUtilities.getString("View_Prev"));
        actionPageDown.addActionListener(this);
        actionPageDown.setBorderPainted(false);
        actionPageDown.setFocusPainted(false);
        // actionPageDown.setToolTipText(BasicUtilities.getString("View_Next"));
        // txtFilter.setToolTipText(BasicUtilities.getString("Filter_Input_Tip"));
        txtFilter.getDocument().addDocumentListener(this);
        lblFilter.setFont(lblFilter.getFont().deriveFont(9.0f));

        Object UI_CONSTRAINT = null;

        parentComponent.setLayout(new GridBagLayout());
        UI_CONSTRAINT = constrain(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL);
        parentComponent.add(glue, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL);
        parentComponent.add(lblSearch, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(2, 0, 1, 1, 0.35, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
        parentComponent.add(txtFilter, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE);
        parentComponent.add(btnHider, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(2, 1, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE);
        parentComponent.add(lblFilter, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(0, 2, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH);
        parentComponent.add(jspTable, UI_CONSTRAINT);
        UI_CONSTRAINT = constrain(1, 3, 4, 1, 1.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE);
        parentComponent.add(lblLocatr, UI_CONSTRAINT);
    }

    public void setModel(EnhancedTableModel model) {

        table.setModel(model);
        if (model.getTrueRowCount() >= 1) {
            table.setRowSelectionInterval(0, 0);
        }

        if (model.getPageCount() > 1) {
            jspTable.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
            jspTable.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            jspTable.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, actionPageUp);
            jspTable.setCorner(ScrollPaneConstants.LOWER_RIGHT_CORNER, actionPageDown);
        } else {
            jspTable.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            jspTable.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
            jspTable.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, Box.createHorizontalStrut(0));
            jspTable.setCorner(ScrollPaneConstants.LOWER_RIGHT_CORNER, Box.createHorizontalStrut(0));
        }
    }

    public EnhancedTable getTable() {

        return table;
    }

    public void clearFiltering() {

        if (table != null) {
            ResultSetTableModel model = (ResultSetTableModel) table.getModel();
            model.clearFilter();
        }
        txtFilter.setText(null);
        lblFilter.setText(null);
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
     */
    public void changedUpdate(DocumentEvent e) {

    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
     */
    public void insertUpdate(DocumentEvent e) {

        doFiltering();
    }

    /*
     * (non-Javadoc)
     * 
     * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
     */
    public void removeUpdate(DocumentEvent e) {

        doFiltering();
    }

    private synchronized void doFiltering() {

        if (table != null) {
            EnhancedTableModel model = (EnhancedTableModel) table.getModel();
            String filter = txtFilter.getText().trim();
            int found = model.applyFilter(filter);
            if (found >= 1) {
                String txt = messages.format("datagrid.found_matches", Integer.toString(found));
                lblFilter.setText(txt);
            } else {
                if (filter.length() >= 1) {
                    lblFilter.setText(messages.getMessage("datagrid.no_matches"));
                } else {
                    lblFilter.setText(null);
                }
            }
            if (table.getRowCount() >= 1) {
                table.setRowSelectionInterval(0, 0);
            }
            table.invalidate();
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent e) {

        Object src = e.getSource();
        if (src == btnHider) {
            txtFilter.setVisible(!txtFilter.isVisible());
            lblFilter.setVisible(!lblFilter.isVisible());
            lblSearch.setVisible(!lblSearch.isVisible());
            glue.setVisible(!glue.isVisible());
            if (txtFilter.isVisible()) {
                btnHider.setIcon(new SortableHeaderRenderer.BasicArrowIcon(SwingConstants.NORTH, 4));
                // btnHider.setToolTipText(BasicUtilities.getString("Filter_Hide_Tip"));
            } else {
                btnHider.setIcon(new SortableHeaderRenderer.BasicArrowIcon(SwingConstants.SOUTH, 4));
                // btnHider.setToolTipText(BasicUtilities.getString("Filter_Show_Tip"));
            }
            btnHider.getParent().validate();
            btnHider.getParent().repaint();
        } else if (src == actionPageDown) {
            EnhancedTableModel model = (EnhancedTableModel) table.getModel();
            model.pageDown();
        } else if (src == actionPageUp) {
            EnhancedTableModel model = (EnhancedTableModel) table.getModel();
            model.pageUp();
        }
    }

    public void valueChanged(ListSelectionEvent e) {

        EnhancedTableModel model = (EnhancedTableModel) table.getModel();
        String str = nf.format(model.translateRow(table.getSelectedRow()) + 1);
        str = str.concat("/");
        str = str.concat(nf.format(model.getTrueRowCount()));
        str = str.concat(" [");
        str = str.concat(nf.format(model.getPageOffset() + 1));
        str = str.concat("/");
        str = str.concat(nf.format(model.getPageCount()));
        lblLocatr.setText(" ".concat(str).concat("] "));
    }
}